﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Speech.Synthesis;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace 初始测试.Tools
{
    public class AudioHandle
    {
        private static string SelectedVoice = "";
        private static AutoResetEvent ResetEvent = new AutoResetEvent(false);
        public static void StartAudioCollect()
        {
            // 定义音频录制参数        
            int sampleRate = 16000;
            // 采样率        
            int channels = 2;
            // 双声道        
            int bitsPerSample = 16;
            // 每个样本的位数
            // 创建一个波形输入设备        
            using (var waveIn = new WaveInEvent())
            {
                // 设置波形输入设备的参数            
                waveIn.WaveFormat = new WaveFormat(sampleRate, bitsPerSample, channels);
                // 创建一个波形文件写入器，用于将音频数据写入文件            
                string outputFilePath = "output.wav";
                using (var waveFile = new WaveFileWriter(outputFilePath, waveIn.WaveFormat))
                {
                    // 订阅数据可用事件                
                    waveIn.DataAvailable += (s, e) =>
                    {
                        // 将缓冲区的数据写入文件                    
                        waveFile.Write(e.Buffer, 0, e.BytesRecorded);
                    };
                    // 订阅录制停止事件                
                    waveIn.RecordingStopped += (s, e) =>
                    {
                        Debug.WriteLine("录制已停止。");
                    };
                    // 开始录制                
                    waveIn.StartRecording();    // 报错： NAudio.MmException:“InvalidParameter calling waveInOpen”
                    Debug.WriteLine("按任意键停止录制...");
                    ResetEvent.WaitOne();
                    // 停止录制
                    waveIn.StopRecording();
                }
            }
            Debug.WriteLine("音频文件已保存到: " + Path.GetFullPath("output.wav"));
        }

        public static void StopAudioCollect()
        {
            ResetEvent.Set();
        }

        public static string ParseWords()
        {
            StringBuilder builder = new StringBuilder();
            // 指定模型路径和音频文件路径
            string modelPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Models", "vosk-model-small-cn-0.22");
            string audioFile = "output.wav";
            if(!Directory.Exists(modelPath))
            {
                return "";
            }
            // 初始化 Vosk
            Vosk.Vosk.SetLogLevel(0);
            try
            {
                using (var model = new Vosk.Model(modelPath))
                using (var recognizer = new Vosk.VoskRecognizer(model, 16000.0f)) // 报错： System.AccessViolationException:“Attempted to read or write protected memory. This is often an indication that other memory is corrupt.”
                using (var waveStream = new WaveFileReader(audioFile))
                {
                    // 重采样到 16kHz (如果需要)        
                    var outFormat = new WaveFormat(16000, 1);
                    using (var resampler = new MediaFoundationResampler(waveStream, outFormat))
                    {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = resampler.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            if (recognizer.AcceptWaveform(buffer, bytesRead))
                            {
                                // 处理中间结果（如果需要）                
                            }
                        }
                    }
                    // 获取最终识别结果        
                    JToken token = JToken.Parse(recognizer.FinalResult());
                    string text = token.Value<string>("text").Replace(" ", "");
                    //var result = JsonDocument.Parse(recognizer.FinalResult());
                    //string text = result.RootElement.GetProperty("text").GetString() ?? string.Empty;
                    builder.Append(text);
                }
            }
            finally
            {
                // 清理临时 WAV 文件    
                //if (File.Exists(audioFile))
                //{
                //    try
                //    {
                //        File.Delete(audioFile);
                //    }
                //    catch
                //    { /* 忽略删除失败 */ }
                //}
            }
            return builder.ToString();
        }

        // 列出当前系统可用的设备信息
        public static void ListSupportedAudioFormats()
        {
            int deviceCount = WaveIn.DeviceCount;

            for (int i = 0; i < deviceCount; i++)
            {
                var capabilities = WaveIn.GetCapabilities(i);
                Debug.WriteLine($"Device {i}: {capabilities.ProductName}");
                Debug.WriteLine($"  Channels: {capabilities.Channels}");

                // 输出支持的采样率和位深度
                Debug.WriteLine("  Supported Formats:");
                // 请注意：NAudio 不直接提供采样率和位深度的支持，但你可以根据 Channels 和其他信息推测
                Debug.WriteLine("  - 16-bit PCM");
                Debug.WriteLine("  - 8-bit PCM");
                Debug.WriteLine("  - Common sample rates: 8000 Hz, 16000 Hz, 44100 Hz, 48000 Hz");

                // 如果需要更详细的信息，可以进一步探索 capabilities
            }

            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_1M08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_1S08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_1M16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_1S16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_2M08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_2S08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_2M16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_2S16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_44M08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_44S08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_44M16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_44S16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_48M08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_48S08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_48M16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_48S16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_96M08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_96S08 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_96M16 |
            // NAudio.Wave.SupportedWaveFormat.WAVE_FORMAT_96S16
        }

        public static void SpeekText(string text)
        {
            using(SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                // 设置语音的音量和语速（可选）
                synthesizer.Rate = 1; // 语速，-10 到 +10
                synthesizer.Volume = 100; // 音量，0 到 100
                synthesizer.SetOutputToDefaultAudioDevice();//输出到默认音频设备
                // 设置语音包
                if(!string.IsNullOrEmpty(SelectedVoice))
                    synthesizer.SelectVoice(SelectedVoice);
                // 将文本转换成语音
                synthesizer.Speak(text);
            }
        }

        // 列出当前系统所有可用的语音包
        public static List<string> ListSupportedVoice()
        {
            List<string> list = new List<string>();
            using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                // 获取可用的语音
                Console.WriteLine("可用的语音:");
                foreach (var voice in synthesizer.GetInstalledVoices())
                {
                    Debug.WriteLine($"- {voice.VoiceInfo.Name}");
                    list.Add(voice.VoiceInfo.Name);
                }

                //// 选择语音
                //Console.Write("请输入要使用的语音名称: ");
                //string selectedVoice = Console.ReadLine();

                //// 设置选择的语音
                //synthesizer.SelectVoice(selectedVoice);

                //// 播报文本
                //Console.Write("请输入要播报的文本: ");
                //string textToSpeak = Console.ReadLine();
                //synthesizer.Speak(textToSpeak);
            }
            return list;
        }

        public static void SetVoiceType(string selectedVoice)
        {
            SelectedVoice = selectedVoice;
        }
    }
}
